
`include "instr_dec_defs.v"

`timescale 1ns / 1ps

module tb_seq;

parameter CLK_PERIOD = 10;

reg clk;
reg i_cin;
reg i_oe;
reg i_cc;
reg i_ccen;
reg [3:0] i_instr;
reg i_rld;
reg [11:0] i_data;

wire o_en_pl;
wire o_en_map;
wire o_en_vect;
wire o_full;
wire [11:0] o_data;

wire [15:0] w_micro_mem_to_pipe_reg;
wire [15:0] w_pipe_reg_to_seq;

seq seq_DUT( 
	.clk(clk),
	.i_cin(i_cin),
	.i_cc(i_cc),
	.i_ccen(i_ccen),
	.i_oe(i_oe),
	.i_rld(i_rld),
	.i_data(w_pipe_reg_to_seq[11:0]),
	.i_instr(w_pipe_reg_to_seq[15:12]),
	.o_full(o_full),
	.o_en_pl(o_en_pl),
	.o_en_map(o_en_map),
	.o_en_vect(o_en_vect),	
	.o_data(o_data)
);

pipe_reg pipe_reg_DUT(
	.clk(clk),
	.i_data(w_micro_mem_to_pipe_reg),
	.o_data(w_pipe_reg_to_seq)
);

micro_mem micro_mem_DUT(
	.i_addr(o_data),
	.o_data(w_micro_mem_to_pipe_reg)
);

initial
begin
	clk = 0;
	i_cin = 1;
	i_oe = 1;
	i_rld = 0;
	i_cc = 1;
	i_ccen = 1;
	
	init_micro_mem;
	
	run_cycles( 20 );				
	
	#10
	$finish;
	
end

always
	#(CLK_PERIOD/2) clk = ~clk;

task instr_set;
	input [3:0] instr;
begin
	#10
		i_instr = instr;
end 
endtask

task instr_set_rep;
	input [3:0] instr;
	input integer rep;
begin
   repeat( rep )
   begin
	#10
		i_instr = instr;
	end
end 
endtask

task data_set;
	input [11:0] data;
begin
	i_data = data;
end 
endtask

task test01;
begin
	instr_set( `ID_INSTR_CONT );
	instr_set( `ID_INSTR_CONT );
	instr_set( `ID_INSTR_CONT );
	data_set( 100 );
	instr_set( `ID_INSTR_LDCT );
	instr_set( `ID_INSTR_CONT );
	instr_set( `ID_INSTR_CONT );
	instr_set( `ID_INSTR_CJS );
	instr_set( `ID_INSTR_CONT );
	instr_set( `ID_INSTR_CONT );
	instr_set_rep( `ID_INSTR_PUSH, 2 );	
end
endtask

task test02;
begin
	data_set( 3 );
	instr_set( `ID_INSTR_LDCT );
	instr_set( `ID_INSTR_CONT );
	data_set( 200 );
	instr_set_rep( `ID_INSTR_RPCT, 4 );
	instr_set( `ID_INSTR_CONT ); 	
end
endtask

task init_micro_mem;
begin
	$readmemh("micro_mem.mem", micro_mem_DUT.mem );	
end
endtask

task run_cycles;
	input integer cycles_no;
begin
	repeat( cycles_no ) begin
		#10
		;
		// nothing
	end
end
endtask

endmodule
